﻿using Blm.PgsqlDriver.Helpers;
using Blm.RabbitMQ.MessageQueue;
using Blm.RabbitMQ.Models;
using Meta.RabbitMQ.Generic;
using Microsoft.Extensions.Logging;
using RabbitMQ.Client;
using System;
using System.Threading.Tasks;
using VisionCloud.Core.Model.Ms;
using VisionCloud.Domain.DtoModel.Ms;
using VisionCloud.Domain.DtoModel.RabbitMq;
using VisionCloud.Domain.Repository.Interface.Ms;
using VisionCloud.Domain.UnitOfWork;
using VisionCloud.Service.Ms;

namespace VisionCloud.Web.Service.MQListener
{
    public class UpdateTaskStatisticsBackgroundService : BlmRabbitMQStorageSubscriberBase<MsTaskStatisticsDto>
    {
        private readonly ILogger<UpdateTaskStatisticsBackgroundService> logger;
        private readonly TaskDataUploadService taskDataUploadService;
        private readonly IUnitOfWork unitOfWork;
        private readonly IMsTaskRepository msTaskRepository;
        private readonly IMsTaskDotCloudRepository msTaskDotCloudRepository;
        private readonly IMsSPersonnelEfficiencyRepository msSPersonnelEfficiencyRepository;

        public UpdateTaskStatisticsBackgroundService(IServiceProvider serviceProvider,
            ILogger<UpdateTaskStatisticsBackgroundService> logger,
            TaskDataUploadService taskDataUploadService,
            IUnitOfWork unitOfWork,
            IMsTaskRepository msTaskRepository,
            IMsTaskDotCloudRepository msTaskDotCloudRepository,
            ICSMSTaskRepository csMSTaskRepository,
            IMsSPersonnelEfficiencyRepository msSPersonnelEfficiencyRepository) : base(serviceProvider)
        {
            this.logger = logger;
            this.taskDataUploadService = taskDataUploadService;
            this.unitOfWork = unitOfWork;
            this.msTaskRepository = msTaskRepository;
            this.msTaskDotCloudRepository = msTaskDotCloudRepository;
            this.msSPersonnelEfficiencyRepository = msSPersonnelEfficiencyRepository;
        }

        public override StorageWayEm StorageWay => StorageWayEm.OnlyStorage;

        public override ClientOption ClientOption => new ClientOption("visioncloud.statistics.update.ex", "visioncloud.statistics.update.rk", ExchangeType.Topic, "visioncloud.statistics.update.queue", RabbitMQConnectPoolName.CloudServerHost);

        public override async Task InvokeAsync(MsTaskStatisticsDto model)
        {
            try
            {
                if (model is null || model.TaskId == Guid.Empty)
                    return;

                var info = await msTaskRepository.GetTaskStatisticsInfoAsync(model.TaskId);
                if (info is null)
                    throw new Exception($"获取任务基本信息为空：TaskId = {model.TaskId}");

                Parallel.Invoke(() => UpdateMsSQualityAnalysis(model, info),
                    async () => await UpdateMsSPersonnelEfficiency(model, info));
            }
            catch (Exception ex)
            {
                logger.LogError($"更新任务数据分析出错：{ex.Message}，{ex.StackTrace}", ex);
            }
        }

        /// <summary>
        /// 更新质量分析
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="info"></param>
        private void UpdateMsSQualityAnalysis(MsTaskStatisticsDto dto, MsTaskStatisticsInfo info)
        {
            try
            {
                var sql = $@"SELECT * FROM ""MsDataStatistics"" where ""TaskId"" = '{dto.TaskId}'";
                var ds = PgSqlHelper.ExecuteDataSet(sql);
                if (ds is null || ds.Tables.Count == 0)
                {
                    logger.LogInformation($"未查询到质量分析数据：TaskId = {dto.TaskId}");
                    return;
                }

                ds.Tables[0].TableName = "MsDataStatistics";
                var isSuccess = taskDataUploadService.UpdateMsSQualityAnalysisTable(ds, info);
                if (!isSuccess)
                {
                    logger.LogError($"更新质量分析表失败：TaskId = {dto.TaskId}");
                    return;
                }
            }
            catch (Exception ex)
            {
                logger.LogError($"更新质量分析表出错：{ex.Message}，{ex.StackTrace}", ex);
            }
        }

        /// <summary>
        /// 更新工效分析
        /// </summary>
        /// <param name="dto"></param>
        /// <param name="info"></param>
        private async Task UpdateMsSPersonnelEfficiency(MsTaskStatisticsDto dto, MsTaskStatisticsInfo info)
        {
            try
            {
                var year = dto.FinishTime.Year;
                var month = dto.FinishTime.Month;
                var day = dto.FinishTime.Day;
                var week = TaskDataUploadService.WeekOfYear(dto.FinishTime);
                var count = msTaskDotCloudRepository.Where(p => p.TaskId == dto.TaskId && p.ComputeStatus == 4).Count;
                var statistics = msSPersonnelEfficiencyRepository.FirstOrDefault(p => p.TaskId == dto.TaskId);
                if (statistics != null)
                {
                    statistics.Year = year;
                    statistics.Month = month;
                    statistics.Day = day;
                    statistics.Week = week;
                    statistics.WeekInfo = week.ToString();
                    statistics.CompletedPointCount = count;
                    msSPersonnelEfficiencyRepository.Update(statistics, t => new { t.Year, t.Month, t.Day, t.Week, t.WeekInfo, t.CompletedPointCount, t.LastUpdatedDate });
                }
                else
                {
                    statistics = new MsSPersonnelEfficiency()
                    {
                        MsPersonnelEfficiencyGuid = Guid.NewGuid(),
                        ProjectGuid = info.ProjectGuid,
                        ProjectNum = info.ProjectNo,
                        ProjectStandardName = info.ProjectStage,
                        BuildingNum = info.BuildingName,
                        FloorNum = info.FloorName,
                        TaskProperty = info.TaskProperty,
                        TaskTypeName = info.TaskType.ToString(),
                        CompanyGuid = info.CompanyGuid,
                        HouseMapId = info.HouseMapId,
                        TaskId = dto.TaskId,
                        UserGuid = info.UserId,
                        CreatedBy = info.UserId,
                        CreatedDate = DateTime.Now,
                        LastUpdatedBy = info.UserId,
                        LastUpdatedDate = DateTime.Now,
                        Year = year,
                        Month = month,
                        Day = day,
                        Week = week,
                        WeekInfo = week.ToString(),
                        CompletedPointCount = count
                    };
                    msSPersonnelEfficiencyRepository.Add(statistics, false);
                }
                var affrows = await unitOfWork.SaveChangesAsync();
                var message = affrows > 0 ? "成功" : "失败";
                logger.LogInformation($"更新工效分析表{message}：TaskId = {dto.TaskId}");
            }
            catch (Exception ex)
            {
                logger.LogError($"更新工效分析表出错：{ex.Message}，{ex.StackTrace}", ex);
            }
        }
    }
}